package com.lfy.commons.aspect;

import com.lfy.auth.domain.entity.UserEntity;
import com.lfy.common.constant.ChatReidsConstant;
import com.lfy.common.enums.BaseEnum;
import com.lfy.common.result.R;
import com.lfy.commons.anno.chat.AddFriendVerification;
import com.lfy.commons.anno.chat.FriendVerification;
import com.lfy.commons.config.interceptor.AuthHandlerInterceptor;
import com.lfy.commons.utils.JsonUtils;
import com.lfy.commons.utils.RedisUtil;
import com.lfy.commons.utils.SpElUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 前置的校验
 * @author 吕飞扬
 */
@Aspect
@Component
@Order(999)
public class AspectFriendVerification {
    @Pointcut(value = "@annotation(com.lfy.commons.anno.chat.FriendVerification)")
    public void cut(){

    }
    @Pointcut(value = "@annotation(com.lfy.commons.anno.chat.AddFriendVerification)")
    public void addFriendCut(){

    }

    /**
     * 发送消息前校验
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around(value = "cut()")
    public Object sendMsgCheck(ProceedingJoinPoint joinPoint) throws Throwable {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        FriendVerification annotation = method.getAnnotation(FriendVerification.class);
        String el = annotation.el();
        String friendId = SpElUtils.parseSpEl(method, joinPoint.getArgs(), el);
        if(StringUtils.isEmpty(friendId)){
            return R.error(BaseEnum.commonEnum.ERROR_SEND_MSG);
        }
        UserEntity user = AuthHandlerInterceptor.authLocal.get();
        Set<String> friends = RedisUtil.sGet(ChatReidsConstant.FRIEND_LIST_PREFIX.concat(user.getId().toString()));
        if(CollectionUtils.isEmpty(friends)){
            return R.error(BaseEnum.commonEnum.ERROR_SEND_MSG);
        }
        Set<String> set = friends.stream().map(item -> JsonUtils.toObj(item, String.class)).collect(Collectors.toSet());
        if(!set.contains(friendId)){
            return R.error(BaseEnum.commonEnum.ERROR_SEND_MSG);
        }
        return joinPoint.proceed();
    }

    /**
     * 发送验证消息前校验
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around(value = "addFriendCut()")
    public Object addFriendCheck(ProceedingJoinPoint joinPoint) throws Throwable {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        AddFriendVerification annotation = method.getAnnotation(AddFriendVerification.class);
        String el = annotation.el();
        String friendId = SpElUtils.parseSpEl(method, joinPoint.getArgs(), el);
        if(StringUtils.isEmpty(friendId)){
            return R.error(BaseEnum.commonEnum.ERROR_PARAMS);
        }
        UserEntity user = AuthHandlerInterceptor.authLocal.get();
        Set<String> strings = RedisUtil.sGet(ChatReidsConstant.FRIEND_LIST_PREFIX.concat(user.getId().toString()));
        if(CollectionUtils.isEmpty(strings)){
           return joinPoint.proceed();
        }
        Set<String> set = strings.stream().map(item -> JsonUtils.toObj(item, String.class)).collect(Collectors.toSet());
        if(set.contains(friendId)){
            return R.error(BaseEnum.commonEnum.ERROR_ADD_FRIEND);
        }
        return joinPoint.proceed();

    }
}
